State Machines topic
Once a state tree has been defined, a state machine can be created.
var stateTree = defineStateTree();
var stateMachine = TreeStateMachine(stateTree);
Starting a state machine
Before messages can be sent to the state machine for processing, it has be started. The start
method returns a future that yields a CurrentState
that serves as a proxy to the current state
after the machine has fully started.
var currentState = await stateMachine.start();
Once the state machine has started, the current state will be the state that was selected by following the initial child path, starting from the root state, as defined by the state tree.
Sending messages
Once a state machine has started, a message may be dispatched to the current leaf state using the
post
method of CurrentState
. This returns a future that completes when the message has been
processed and any resulting transition has completed. Note that any object can be posted, there is
no requirement for a common message base class.
var message = SubmitCredentials(username: 'foo', password: 'bar');
ProcessedMessage messageResult = await currentState.post(message);
The ProcessedMessage
base class describes how the message was processed. Further information about
what occurred by pattern matching on its subclases HandledMessge
, UnhandledMessage
, and
FailedMessage
.
State machine streams
In addition to inspecting the results of post
to learn about how a message was processed, it is
also possible to subscribe to several stream properties of TreeStateMachine
:
processedMessages
yields an event for every message that is processed by the tree, whether or not the message was handled successfully, and whether or not a transition occurred as a result of the message.handledMessages
is a convenience stream that yield an event when only when a message is successfully handled. Note that the HandledMessage event is also emitted on the processedMessages stream.transitions
yields an event each time a transition between states occurs.
Data streams
Both TreeStateMachine
and CurrentState
have a dataStream
method. This returns a ValueStream
for a data state, allowing an application to observe changes to state data over time.
// Observe changes to state data for the 'register' data state.
var subscription = stateMachine
.dataStream(States.register)
.listen((RegisterData data) {
print(data.email);
});
While both methods can return a stream, they differ slightly in their use:
CurrentState.dataStream
returns a stream for an active data state. If the requested state is not active,null
is returned. Additionally, the returned stream will complete when the state is no longer active (in other words, after theonExit
notification for the state).TreeStateMachine.dataStream
returns a stream, regardless of whether the requested data state is active or not. This can be useful for observing state data over the full lifetime of the state machine. A consequence of this is that the stream will not complete unless the state machine is stopped, so it may be necessary for an app to explicitly cancel the subscription, depending on the circumstances.
Ending a state machine
A state machine can end in two ways.
- When processing a message, if the state machine transitions to a final state, then no other message processing or state transitions will occur, and the state machine has ended. This is called an 'internal stop'.
- Calling
stop
on the state machine will transition the machine to an implicit final state, identified bystoppedStateKey
. This state will always be available, and does not need to be added when defining a state tree. This is called an 'external stop'.await stateMachine.stop(); // done will be true after stopping. var done = stateMachine.isDone;
State machine logging
The tree_state_machine
package logs diagnostic messages using the Dart SDK logging
package. In
order to view this output in the Dart developer console:
- Set
hierarchicalLoggingEnabled
from thelogging
package totrue
before creating a state machine - Set
enableDeveloperLogging
totrue
when creating the state machine.
Classes
- TreeStateMachine Getting Started State Machines
- A state machine that manages transitions among the states in a state tree.